package com.example.tool.es;


import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.example.tool.ck.TextUtils;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;

import java.io.IOException;
import java.util.Calendar;
import java.util.Date;

public class Es7Client {

    public static RestHighLevelClient restHighLevelClient(){


        RestClientBuilder builder = RestClient.builder(new HttpHost(TextUtils.queryAndGetText("online.es7.hostname"),
                Integer.parseInt(TextUtils.queryAndGetText("online.es7.port")), "http"));
        //builder = RestClient.builder(new HttpHost(TextUtils.queryAndGetText("test.es7.hostname"),
               // Integer.parseInt(TextUtils.queryAndGetText("test.es7.port")), "http"));

        // 创建自定义的Gson对象
//        Gson gson = new GsonBuilder()
//                .setDateFormat("yyyy-MM-dd HH:mm:ss")
//                // 根据需要添加其他配置
//                .create();
        // 设置自定义的Gson到RestClientBuilder
        builder.setRequestConfigCallback(new RestClientBuilder.RequestConfigCallback() {
            @Override
            public RequestConfig.Builder customizeRequestConfig(RequestConfig.Builder builder) {
                builder.setConnectTimeout(60000)
                        .setSocketTimeout(60000);
                return builder;
            }
        });

        // 设置自定义的Gson到RestHighLevelClient
        builder.setRequestConfigCallback(requestConfigBuilder -> {
            requestConfigBuilder.setContentCompressionEnabled(true);
            return requestConfigBuilder;
        });
        // 创建RestHighLevelClient实例
        RestHighLevelClient client = new RestHighLevelClient(builder);
        return client;
    }


    public static SearchHits searchList(SearchSourceBuilder searchSourceBuilder, String indexName) throws IOException {
        RestHighLevelClient restHighLevelClient = null;
        try {
            restHighLevelClient = restHighLevelClient();
            SearchRequest searchRequest = new SearchRequest(indexName);
            searchRequest.source(searchSourceBuilder);
            SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            return search.getHits();
        }finally {
            if(restHighLevelClient!=null){
                restHighLevelClient.close();
            }
        }

    }

    public static JSONObject searchPage(SearchSourceBuilder searchSourceBuilder, Integer pageNo, String indexName) throws IOException {
        RestHighLevelClient restHighLevelClient = null;
        try {
            restHighLevelClient = restHighLevelClient();
            SearchRequest searchRequest = new SearchRequest(indexName);
            searchSourceBuilder.sort(new FieldSortBuilder("startTime")
                    .order(SortOrder.DESC)).from(pageNo*10-10).size(10);
            searchRequest.source(searchSourceBuilder);
            SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            JSONObject page = new JSONObject();
            TotalHits totalHits = search.getHits().getTotalHits();
            page.put("total",totalHits.value);
            SearchHit[] hits = search.getHits().getHits();
            JSONArray list = new JSONArray();
            for (SearchHit hit : hits) {
                String sourceAsString = hit.getSourceAsString();
                list.add(JSONObject.parseObject(sourceAsString));
            }
            page.put("data",list);
            return page;
        }finally {
            if(restHighLevelClient!=null){
                restHighLevelClient.close();
            }
        }

    }
    /**
     * @Author DZLWL
     * @Date 2020/6/30 10:06
     * @desc 通用增加时间 type是要添加的类型  duration是添加时长
     */
    public static Date addTime(Date date, Integer type, Integer duration) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(type, duration);
        Date time = cal.getTime();
        return time;
    }
    public static JSONObject statisticsTask(SearchSourceBuilder sourceBuilder, String indexName) throws IOException {

        RestHighLevelClient restHighLevelClient = null;
        try {
            restHighLevelClient = restHighLevelClient();
            SearchRequest searchRequest = new SearchRequest(indexName);
            sourceBuilder
                    // 账号 任务数  折线图/柱状图
                    .aggregation(
                            AggregationBuilders.terms("accountIdGroup").field("accountId")
                                    .size(9999)
                    )
                    // 状态饼图
                    .aggregation(
                    AggregationBuilders.terms("statusGroup").field("status").size(10).minDocCount(1))
                    // 来源
                   .aggregation(
                                    AggregationBuilders.terms("sourceGroup").field("source").size(100).minDocCount(1))
                    .aggregation(
                            AggregationBuilders.terms("finishGroup").field("finish").size(3).minDocCount(1))
                    // 饼图  30s以内   60s 以内   5min以内   10min以内  10min外
                    .aggregation(
                            AggregationBuilders.range("costRange").field("cost")
                                    .addRange(0,30*1000d)
                                    .addRange(30*1000d,60*1000d)
                                    .addRange(60*1000d,300*1000d)
                                    .addRange(300*1000d,600*1000d)
                                    .addRange(600*1000d,Integer.MAX_VALUE)
                    )
                    // 24h 任务柱状图或者折线图  范围分组
                    .aggregation(
                            AggregationBuilders.dateHistogram("startTimeRange").field("startTime")
                                    .fixedInterval(DateHistogramInterval.HOUR)
                    );
            sourceBuilder.size(0).trackTotalHits(true);
            searchRequest.source(sourceBuilder);
            SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            JSONObject page = new JSONObject();
            TotalHits totalHits = search.getHits().getTotalHits();
            page.put("total",totalHits.value);
            Aggregation statusGroup = search.getAggregations().get("statusGroup");
            Aggregation accountIdGroup = search.getAggregations().get("accountIdGroup");
            Aggregation sourceGroup = search.getAggregations().get("sourceGroup");
            Aggregation finishGroup = search.getAggregations().get("finishGroup");
            Aggregation costRange = search.getAggregations().get("costRange");
            Aggregation startTimeRange = search.getAggregations().get("startTimeRange");
            page.put("status",statusGroup);
            page.put("accountId",accountIdGroup);
            page.put("source",sourceGroup);
            page.put("finish",finishGroup);
            page.put("cost",costRange);
            page.put("startTime",startTimeRange);
            return page;
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if(restHighLevelClient!=null){
                restHighLevelClient.close();
            }
        }
    }

    public static JSONObject statisticsHeader(Integer taskType, Date runDate, String indexName) {

        RestHighLevelClient restHighLevelClient = null;
        try {
            restHighLevelClient = restHighLevelClient();
            SearchRequest searchRequest = new SearchRequest(indexName);
            SearchSourceBuilder sourceBuilder  = new SearchSourceBuilder();
            sourceBuilder.query(QueryBuilders.boolQuery()
                    .filter(QueryBuilders.termQuery("taskType",taskType))
                    .filter(QueryBuilders.termQuery("runDate", DateUtil.format(runDate,"yyyyMMdd")))
            );
            sourceBuilder
                    // 账号 任务数  折线图/柱状图
                    .aggregation(
                            AggregationBuilders.terms("sourceGroup").field("source")
                                    .size(9999)
                    )
                    // 状态饼图
                    .aggregation(
                            AggregationBuilders.terms("serviceNameGroup").field("serviceName").size(100).minDocCount(1))
                    ;
            sourceBuilder.size(0).trackTotalHits(true);
            searchRequest.source(sourceBuilder);
            SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            JSONObject page = new JSONObject();
            TotalHits totalHits = search.getHits().getTotalHits();
            page.put("total",totalHits.value);
            Aggregation sourceGroup = search.getAggregations().get("sourceGroup");
            Aggregation finishGroup = search.getAggregations().get("serviceNameGroup");
            page.put("source",sourceGroup);
            page.put("serviceName",finishGroup);
            return page;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if(restHighLevelClient!=null){
                try {
                    restHighLevelClient.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
